home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
pascal
/
fin_tp.exe
/
FINANCE.PAS
Wrap
Pascal/Delphi Source File
|
1990-01-20
|
7KB
|
193 lines
{==============================================================}
{ Saved as: FINANCE.PAS }
{ Author: Pat Anderson }
{ Purpose: Service routines for loan }
{ payment and amortization }
{ program }
{ Last modified: January 20, 1990 }
{ }
{==============================================================}
UNIT Finance;
{--------------------------------------------------------------}
INTERFACE
{--------------------------------------------------------------}
USES crt;
TYPE
AmortRecType = RECORD { Record type for }
InterestPart, { results of Amortize }
PrincipalPart, { procedure }
NewBalance : real;
END;
VAR
AmortRecord : AmortRecType;
FUNCTION Form (number : real) : string;
{ Function to return a real number as a string
formatted with a dollar sign and commas }
FUNCTION Raise (Number, Power : real) : real;
PROCEDURE Amortize (Principal, Payment, InterestRate,
PaymentsPerYear : real);
{ Procedure to calculate the amortization resulting from
one payment. Returns the amount of the payment allocated
to interest and principal and the resulting new principal
balance in the AmortRecord global variable - used in a
FOR loop from 1 to the term of the loan in months to
generate an amortization table }
FUNCTION CalculatePayment (Principal, InterestRate,
PaymentsPerYear, Years : real) : real;
{ Function to calculate the monthly payment on a loan }
FUNCTION CalculatePrincipal (Payment, InterestRate,
Years, PaymentsPerYear : real) : real;
{ Function to APPROXIMATE the original principal of a loan given
the other factors - approximate because of real number rounding
errors }
FUNCTION CalculateTerm (Principal, Payment,
InterestRate, PaymentsPerYear : real) : real;
{ Function to APPROXIMATE the original term of a loan given the other
factors }
FUNCTION CalculateInterestRate (Principal, Payment,
Years, PaymentsPerYear : real) : real;
{ Function to APPROXIMATE the original interest rate of a loan given
the other factors }
{--------------------------------------------------------------}
IMPLEMENTATION
{--------------------------------------------------------------}
FUNCTION Form (number : real) : string;
VAR
RoundedNumber : longint;
CentsPart,
DollarsPart,
TempStr : string;
DotPos : byte;
OrgLen : byte;
BEGIN
Number := Number * 100;
RoundedNumber := Round (Number);
Str (RoundedNumber, TempStr);
DollarsPart := Copy (TempStr, 1, Length (TempStr) - 2);
CentsPart := Copy (TempStr, Length (TempStr) - 1, 2);
OrgLen := Length (DollarsPart);
IF OrgLen > 3 THEN
BEGIN
IF OrgLen < 7 THEN
Insert (',', DollarsPart, Length (DollarsPart) - 2);
IF OrgLen >= 7 THEN
BEGIN
Insert (',', DollarsPart, Length (DollarsPart) - 5);
Insert (',', DollarsPart, Length (DollarsPart) - 2);
END;
END;
Form := '$' + DollarsPart + '.' + CentsPart;
END;
FUNCTION Raise (Number, Power : real) : real;
BEGIN
Raise := Exp (Power*Ln(Number));
END;
PROCEDURE Amortize (Principal, Payment, InterestRate,
PaymentsPerYear : real);
BEGIN
WITH AmortRecord DO
BEGIN
InterestPart := Principal * (InterestRate/100) * (1/PaymentsPerYear);
PrincipalPart := Payment - InterestPart;
NewBalance := Principal - PrincipalPart;
END;
END;
FUNCTION CalculatePayment (Principal, InterestRate,
PaymentsPerYear, Years : real) : real;
VAR
Numerator,
Denominator,
Denominator2 : real;
BEGIN
InterestRate := InterestRate / 100;
Numerator := InterestRate*(Principal/PaymentsPerYear);
Denominator2 := Raise (InterestRate/PaymentsPerYear+1,
PaymentsPerYear*Years);
Denominator := 1 - (1/Denominator2);
CalculatePayment := Numerator/Denominator;
END;
FUNCTION CalculatePrincipal (Payment, InterestRate,
Years, PaymentsPerYear : real) : real;
VAR
Denominator : real;
BEGIN
InterestRate := InterestRate/100;
Denominator := Raise (1 + InterestRate/PaymentsPerYear,
PaymentsPerYear*Years);
CalculatePrincipal :=
((Payment*PaymentsPerYear)/InterestRate)*(1 - (1/Denominator));
END;
FUNCTION CalculateTerm (Principal, Payment,
InterestRate, PaymentsPerYear : real) : real;
VAR
Numerator,
Denominator : real;
BEGIN
InterestRate := InterestRate/100;
Numerator := Ln (1 - ((Principal*InterestRate)/(PaymentsPerYear*Payment)));
Denominator := Ln (1 + (InterestRate/PaymentsPerYear));
CalculateTerm := -(Numerator/Denominator)*(1/PaymentsPerYear);
END;
FUNCTION CalculateInterestRate (Principal, Payment,
Years, PaymentsPerYear : real) : real;
VAR
LastGuess,
CurrentGuess,
NextGuess,
ComputedPayment,
Change : real;
RoundedComputedPayment,
RoundedPayment : longint;
BEGIN
LastGuess := 0;
NextGuess := 10.0;
Payment := Payment * 100;
RoundedPayment := Round (Payment);
REPEAT
CurrentGuess := NextGuess;
ComputedPayment := CalculatePayment (Principal, NextGuess,
PaymentsPerYear, Years);
ComputedPayment := ComputedPayment * 100;
RoundedComputedPayment := Round (ComputedPayment);
IF RoundedComputedPayment < RoundedPayment THEN
BEGIN
Change := Abs ((CurrentGuess - LastGuess)/2);
LastGuess := CurrentGuess;
NextGuess := CurrentGuess + Change;
END;
IF RoundedComputedPayment > RoundedPayment THEN
BEGIN
Change := Abs ((CurrentGuess - LastGuess)/2);
LastGuess := CurrentGuess;
NextGuess := CurrentGuess - Change;
END;
UNTIL RoundedComputedPayment = RoundedPayment;
CalculateInterestRate := CurrentGuess;
END;
END.